#ifndef __RBL_UNPACK_H_
#define __RBL_UNPACK_H_

#include "fupdate.h"
#if (FBOOT_USING_FUPDATE == 1)

#include "rbl_info.h"
#include "rbl_algo.h"

typedef struct fstorage_interface fstorage_interface_t;

typedef struct rbl_unpack_context
{
	rbl_header_info_t    rbl_header;
	
	fstorage_interface_t * src_interface;
	
	fstorage_interface_t * target_interface;
	
	uint8_t *   rw_buffer;				// fal read write data
	uint8_t *   compress_buffer; // compress data
	
	void *      decompress_qz_ctx;
	void *      decompress_fz_ctx;
	void *      decompress_gzip_ctx;
	
	uint8_t *   decrypt_buffer;	// AES256 decrypt data
	
	void *      decrypt_ctx;
	void *      decrypt_iv;
	void *      decrypt_key;
	
	uint32_t    src_read_total;
	uint32_t    src_read_pos;
	
	uint32_t    target_write_total;
	uint32_t    target_write_pos;
	
} rbl_unpack_context_t;


rbl_unpack_context_t* rbl_unpack_context_create(void); 

void rbl_unpack_context_delete(rbl_unpack_context_t* fupdate_ctx); 


void rbl_unpack_header_show(rbl_header_info_t *p_header);

int rbl_unpack_header_check(rbl_header_info_t *p_header);


int rbl_unpack_context_buffer_init(rbl_unpack_context_t* unpack_ctx);

int rbl_unpack_context_buffer_deinit(rbl_unpack_context_t* unpack_ctx);


int rbl_unpack_header_version_check(rbl_unpack_context_t* unpack_ctx);

int rbl_unpack_header_version_update(rbl_unpack_context_t* unpack_ctx);


int rbl_unpack_body_check(rbl_unpack_context_t* unpack_ctx);

int rbl_unpack_body_output(rbl_unpack_context_t* unpack_ctx);


typedef enum
{
    RBL_UNPACK_ERR_NO = 0,
    RBL_UNPACK_ERR_GENERAL = -1,            /* general error */
    RBL_UNPACK_ERR_OPEN    = -2,            /* storage open error */
    RBL_UNPACK_ERR_READ    = -3,            /* storage read error */
    RBL_UNPACK_ERR_WRITE   = -4,            /* storage write error */
    RBL_UNPACK_ERR_CHECK   = -5,            /* check failed */
    RBL_UNPACK_ERR_ALGO_NOT_SUPPORTED = -6, /* algorithm not supported */
    RBL_UNPACK_ERR_FW_VERIFY_FAILED = -7,   /* verify failed */
    RBL_UNPACK_ERR_NO_MEM     = -8,         /* no memory */
} rt_fota_err_t;


#ifndef RBL_UNPACK_RW_BUFFER_SIZE
#define RBL_UNPACK_RW_BUFFER_SIZE (4096U)
#endif

#ifndef RBL_UNPACK_COMPRESS_BUFFER_SIZE
#define RBL_UNPACK_COMPRESS_BUFFER_SIZE (4096U+ 4096U)
#endif

#define RBL_UNPACK_USING_AES256      FUPDATE_USING_AES256
#define RBL_UNPACK_USING_FASTLZ      FUPDATE_USING_FASTLZ
#define RBL_UNPACK_USING_QUICKLZ     FUPDATE_USING_QUICKLZ
#define RBL_UNPACK_USING_GZIP        FUPDATE_USING_GZIP


#endif /* FBOOT_USING_FUPDATE */

#endif

